package org.nf.box.common.jwt;

import io.jsonwebtoken.JwtBuilder;
import io.jsonwebtoken.Jwts;

import javax.crypto.SecretKey;
import java.security.SecureRandom;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

/**
 * @author lzp
 * @date 2024/12/20
 * JWT工具类
 */
public class JwtUtils {

    /**
     * 验签码
     */
    private static final String SECRET;

    /**
     * 密钥，用于签名和验签（注意：这个KEY是保存在服务端不能被泄露的）
     */
    private static final SecretKey KEY;

    /**
     * Token的签发人
     */
    private static final String ISSUER = "org.nf";

    /**
     * 初始化KEY
     */
    static {
        SECRET = UUID.randomUUID().toString();
        KEY = Jwts.SIG.HS256.key()
                .random(new SecureRandom(SECRET.getBytes()))
                .build();
    }

    /**
     * 创建token
     * @param payload 数据载体
     * @param ttl 过期时间
     * @return JWT
     */
    public static String createToken(Map<String, Object> payload, long ttl) {
        JwtBuilder builder = Jwts.builder()
                //采用HS256加密算法对JWT进行签名
                .signWith(KEY)
                //JWT的唯一标识
                .id(UUID.randomUUID().toString())
                //设置载体内容
                .claims(payload)
                //设置签发人
                .issuer(ISSUER)
                //主题
                .subject("JWT_AUTH")
                //JWT颁发时间
                .issuedAt(new Date());
        //设置过期时间
        if(ttl >= 0) {
            builder.expiration(getExpDate(ttl));
        }
        //创建JWT
        return builder.compact();
    }

    /**
     * 计算过期时间
     * @param ttl
     * @return
     */
    private static Date getExpDate(long ttl) {
        Date expDate = new Date(System.currentTimeMillis() + ttl);
        System.out.println("Token过期时间：" + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(expDate));
        return expDate;
    }

    /**
     * 解析token，获取载体数据
     * @param token JWT
     * @param type 载体数据的类型
     * @return
     * @param <T>
     */
    public static <T> T parseToken(String token, String name, Class<T> type) {
        return Jwts.parser()
                .verifyWith(KEY)
                .build()
                .parseSignedClaims(token)
                .getPayload()
                .get(name, type);

    }

    /**
     * 校验token
     * @param token
     */
    public static void verify(String token) {
        Jwts.parser()
                .verifyWith(KEY)
                .build()
                .parseSignedClaims(token);
    }

    public static void main(String[] args) {
        Map<String, Object> payload = new HashMap<>();
        payload.put("name", "user1");
        System.out.println(JwtUtils.createToken(payload, 1000 * 60 * 60 * 24));
    }
}